package com.rf.richfitwheel.dyn.business.service.impl;

import com.rf.richfitwheel.common.exception.BusinessException;
import com.rf.richfitwheel.dyn.business.service.GenerateIDUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 通过redis计数器实现唯一id
 * @author hushouquan
 * @since 2024/1/11
 */
@Service(value="redisGenerateIDUtil")
public class RedisGenerateIDUtilImpl implements GenerateIDUtil {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    // key前缀
    private static final String GENERATE_ID_PREFIX = "generateId:";
    /**
     * 生成单个简单的分布式唯一ID
     *
     * @param key  业务标识key
     * @param type 1-key+20位数字，2-key+YYYY+20位数字，3-key+YYYYMM+20位数字，
     *             4-key+YYYYMMDD+20位数字，其他-20位数字
     * @param length 长度,2-20
     * @return 分布式唯一id
     */
    @Override
    public String generateId(String key, String type, int length){
        if(length <2 || length > 20){
            throw new BusinessException("位数必须大于等于2或小于等于20");
        }
//        // 获取对应业务自增序列
//        Long increment = getIncrement(key, length);
        LocalDateTime localDateTime = LocalDateTime.now();
        String format = "%0" + length + "d";
        // 组装最后的结果
        switch(type){
            case "1":
                // 获取对应业务自增序列
                return key + String.format(format,getIncrement(key, length));
            case "2":
                return key + localDateTime.format(DateTimeFormatter.ofPattern("yyyy")) + String.format(format,getIncrement(key + localDateTime.format(DateTimeFormatter.ofPattern("yyyy")), length));
            case "3":
                return key + localDateTime.format(DateTimeFormatter.ofPattern("yyyyMM")) + String.format(format,getIncrement(key + localDateTime.format(DateTimeFormatter.ofPattern("yyyyMM")), length));
            case "4":
                return key + localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + String.format(format,getIncrement(key + localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd")), length));
            default :
                return String.format(format,getIncrement(key, length));
        }
    }
    
    /**
     * 批量生成简单的分布式唯一ID
     *
     * @param key    业务标识key
     * @param type   1-key+20位数字，2-key+YYYY+20位数字，3-key+YYYYMM+20位数字，
     *               4-key+YYYYMMDD+20位数字，。。。。。
     * @param counts 数量
     * @param length 长度,2-20
     * @return 分布式唯一id
     */
    @Override
    public List<String> generateIdBatch(String key, String type, int counts, int length){
        List<String> ids = new ArrayList<>();
        for(int i = 0; i < counts; i++){
            ids.add(generateId(key, type, length));
        }
        return ids;
    }
    
    /**
     * 获取对应业务自增序列
     * @param key 业务标识key
     * @param length 长度
     * @return 自增序列
     */
    private Long getIncrement(String key, int length){
        String cacheKey = GENERATE_ID_PREFIX + key + "-" + length;
        return redisTemplate.opsForValue().increment(cacheKey);
    }
}
